import * as constants from '../AppConstants'
import utils from '../commons/utils'
import MDialog from '../views/components/dialog'

/**
 * 业务模块的混合类，包含基本的增删查改功能
 * Created by yangxin on 2017/07/24.
 */
export default {
    components: {
        MDialog
    },
    data () {
      return {
          self: this,                               // 在模板中的table属性 context中使用，可以解决列中render函数中不能调用方法的问题
          moduleRout: '',                          // 模块API的基本路径， 如： “/sys/sysuser”
          deleteDialog: 'deleteMDialog',        // 删除提示对话框的 ref 名称
          listView: 'list',                       // 列表层显示标识
          detailView: 'detail',                  // 详细信息层显示标识
          viewName: 'list',                       // 默认初始显示的层，一般为列表层
          tableRef: 'grid',                       // 默认的table ref
          loading: false,                         // 按钮异步提交等待
          modaling: false,                        // 弹出模块显示参数
          mconst: {                                // 常量，自行扩展
              allText: constants.ALL_TEXT,         // 查询块中显示所有的文字
              gutter: constants.DEFAULT_ROW_GUTTER, // 栅格布局col之间的间隔
              labelWidth: constants.DEFAULT_LABEL_WIDTH,
              status_enabled: constants.STATUS_ENABLED,
              status_disabled: constants.STATUS_DISABLED
          },
          mtypes: {                                // 数组字典，自行扩展
              status: constants.STATUS,            // 状态数组
              sex: constants.SEX,                   // 性别数组
              channels: constants.CHANNELS,         // 渠道数组
              judge: constants.JUDGE                // 判断数组
          },
          query: {                                 // 查询字段
              keyword: {                           // 关键字模糊查询字段
                  value: '',
                  fields: ''
              },
              daterange: {
                  field: '',
                  values: ''
              },
              size: constants.DEFAULT_PAGE_SIZE,     // 每页显示数量
              page: constants.DEFAULT_PAGE_NO,    // 当前页码
              sort: 'id,asc'                            // 排序信息
          },
          data: {
              totalElements: 0,                         // 数据总数
              content: []                                // 数据数组
          },
          exportExcel: {
              renders: {
                  keys: [],
                  selfs: {}
              },
              ext: {}
          },
          suggest: {
              loading: false,
              min: 2,
              options: [],
              query: {                                 // 查询字段
                  keyword: {                          // 关键字模糊查询字段
                      value: '',
                      fields: ''
                  },
                  size: constants.DEFAULT_PAGE_SIZE,     // 每页显示数量
                  page: constants.DEFAULT_PAGE_NO,    // 当前页码
                  sort: 'id,desc'                            // 排序信息
              }
          },
          selection: [],                                 // 被勾选的行数组
          columns: [],                                   // 列信息
          detail: {                                      // 详细信息层
              addModel: true,                           // true表示添加，否则是需求
              loading: false,                         // 按钮异步提交等待
              model: {},                                  // 业务空模块属性,
              rules: {}
          }
      }
    },
    methods: {
        viewShow(viewName) {
          return this.viewName == viewName
        },
        switchListView() {
            this._switchView(this.listView)
        },
        switchDetailView() {
            this._switchView(this.detailView)
        },
        onChangePage(page){
            this.query.page = page-1
            this.loadGrid()
        },
        onChangePageLimit(pagesize){
            this.query.size = pagesize
            this.loadGrid()
        },
        onSortRemote(sort){
            if(!(sort.order == 'asc' || sort.order == 'desc')){
                sort.order = ''
                sort.key = ''
            }
            this.query.sort = [sort.key, sort.order].join(',')
            this.loadGrid()
        },
        onRemoteSuggest(text){
            if(text.length >= this.suggest.min){
                this.suggest.query.keyword.value = text
                this.suggest.loading = true
                this._suggest({
                    query: this.suggest.query,
                    callBack: () => {
                        this.suggest.loading = false
                    }
                })
            }else{
                this.suggest.options = []
            }
        },
        onAdd(){
            this.detail.addModel = true
            this.resetFields('modelForm')
            this.clearModel()
            this.switchDetailView()
            this.afterAdd && this.afterAdd()
        },
        onSelectedRows(selection){
            this.selection = selection
            this.afterSelected && this.afterSelected()
        },
        onShow(index) {
            let row = this.getRow(index)
            this._getModel({
                id: row.id,
                callBack: this.afterShow
            })
        },
        onEdit(index) {
            this.detail.addModel = false
            let row = this.getRow(index)
            this.resetFields('modelForm')
            this._getModel({
                id: row.id,
                callBack: this.afterEdit
            })
        },
        onDelete(index) {
            let $this = this
            let row = this.getRow(index)
            this.$refs[this.deleteDialog].show({
                title: '删除确认',
                content: `确认要删除该信息吗？`,
                btnText: '删除',
                btnType: 'error',
                callback() {
                   $this._deleteModel({
                       id: row.id,
                       callback: $this._afterDelete,
                       errorCall: $this.$refs[$this.deleteDialog].hide
                   })
                }
            })
        },
        onBatchDelete() {
            let $this = this
            let ids = []
            if(this.selection.length == 0){
                this.$Message.error('请至少勾选一条数据')
                return
            }
            this.selection.forEach(function (row) {
                ids.push(row.id)
            })
            this.$refs[this.deleteDialog].show({
                title: '删除确认',
                content: `确认要删除勾选的信息吗？`,
                callback() {
                    $this._deleteBatchModel({
                        ids: ids,
                        callback: $this._afterBatchDelete,
                        errorCall: $this.$refs[$this.deleteDialog].hide
                    })
                }
            })
        },
        onUpdateField(index, name, value, operName) {
            let $this = this
            let id = this.getRow(index).id
            this.$refs[this.deleteDialog].show({
                title: `${operName}确认`,
                content: `确认要${operName}该信息吗？`,
                btnText: `${operName}`,
                callback() {
                    $this._updateField({
                        id: id,
                        field: name,
                        value: value,
                        callBack: () => {
                            $this.$refs[$this.deleteDialog].hide
                            $this.loadGrid()
                        },
                        errorCall: $this.$refs[$this.deleteDialog].hide
                    })
                }
            })
        },
        onBatchUpdateField(name, value, operName) {
            let $this = this
            let ids = []
            if(this.selection.length == 0){
                this.$Message.error('请至少勾选一条数据')
                return
            }
            this.selection.forEach(function (row) {
                ids.push(row.id)
            })
            this.$refs[this.deleteDialog].show({
                title: `${operName}确认`,
                content: `确认要${operName}勾选的信息吗？`,
                btnText: `${operName}`,
                callback() {
                    $this._batchUpdateField({
                        ids: ids,
                        name: name,
                        value: value,
                        callback: $this._afterBatchUpdate,
                        errorCall: $this.$refs[$this.deleteDialog].hide
                    })
                }
            })
        },
        onSave(){
            if(this.valideForm('modelForm')) {
                let cfg = {
                    callBack: this.afterInsertOrUpdate
                }
                this.detail.addModel ? this._insertModel(cfg) : this._updateModel(cfg)
            }
        },
        onExportExcel(){
            this.loading = true
            this._getAll({
                callBack: (data) => {
                    this.loading = false
                    let cfg = this.exportExcel
                    let columns = cfg.columns || this.columns
                    this.$refs[this.tableRef].exportCsv({
                        filename: cfg.filename || '导出数据',
                        columns: cfg.filterColumns?cfg.filterColumns(columns):columns.filter((col, index) => (col.type != 'selection' && col.key != 'action')),
                        data: this._renderExportData(data),
                        original: false
                    })
                }
            })
        },
        onStatusToggle(status){
            var index = event.target.parentNode.parentNode.id.split('_')[1]
            this._updateField({
                id: this.getRow(index).id,
                field: 'states',
                value: status?constants.STATUS_ENABLED:constants.STATUS_DISABLED,
                callBack: () => {
                    this.loadGrid()
                }
            })
        },
        onDateRangeChange(value){
            this.query.daterange.values = value.join(',')
            this.loadGrid()
        },
        afterInsertOrUpdate(){
            this.switchListView()
            this.loadGrid()
            this.detail.addModel?(this.afterInsert && this.afterInsert()):(this.afterUpdate && this.afterUpdate())
        },
        loadGrid(){
            this._list({
                callBack: this.afterLoadGrid
            })
        },
        clearModel(){
            this.detail.model =  {}
        },
        getRow(index){
          return this.data.content[index]
        },
        getColumn(key){
            let filters = this.columns.filter((column, index) => column.key == key)
            return filters.length > 0 ? filters[0]:null
        },
        getColumnRender(key){
            let column = this.getColumn(key)
            return column.render || null
        },
        resetFields(formRef){
            this.$refs[formRef].resetFields()
        },
        valideForm(formRef){
            let valid = false
            this.$refs[formRef].validate(function(v){
                valid = v
            })
            if (!valid) {
                this.$Message.error('表单验证未通过！')
                return false
            }
            this.customValid && (valid = this.customValid(formRef))
            return valid
        },
        getNameByCode(arr, code, props){
            return utils.getNameByCode(arr, code, props)
        },
        _switchView(viewName){
            this.viewName = viewName
        },
        _afterDelete(){
            this.$refs[this.deleteDialog].hide()
            this.afterDelete && this.afterDelete()
        },
        _list(cfg) {
            cfg = cfg || {}
            this.$http.get(this.moduleRout, {params: cfg.query || this.query}).then((resp) => {
                this.data = resp.data
                console.log("list###:"+JSON.stringify(resp.data))
                this.selection = []
                cfg.callBack && cfg.callBack()
            }).catch(console.warn.bind(console))
        },
        _getAll(cfg) {
            cfg = cfg || {}
            this.$http.get(this.moduleRout+'/all', {params: cfg.query || this.query}).then((resp) => {
                //console.log("all###:"+JSON.stringify(resp.data))
                cfg.callBack && cfg.callBack(resp.data)
            }).catch(console.warn.bind(console))
        },
        _getModel(cfg) {
            cfg = cfg || {}
            this.$http.get(this.moduleRout+"/"+cfg.id).then((resp) => {
                this.detail.model = resp.data
                console.log("model###:"+JSON.stringify(resp.data))
                this.afterGetModel && this.afterGetModel(resp.data)
                this.switchDetailView()
                cfg.callBack && cfg.callBack()
            }).catch(console.warn.bind(console))
        },
        _deleteModel(cfg) {
            cfg = cfg || {}
            this.$http.delete(this.moduleRout+"/"+cfg.id).then((resp) => {
                this.loadGrid()
                cfg.callBack && cfg.callBack()
            }).catch(cfg.errorCall())
        },
        _deleteBatchModel(cfg) {
            cfg = cfg || {}
            this.$http.delete(this.moduleRout+"/batch", {params: {ids: cfg.ids.join(',')}}).then((resp) => {
                this.loadGrid()
                cfg.callBack && cfg.callBack()
            }).catch(cfg.errorCall())
        },
        _insertModel(cfg) {
            cfg = cfg || {}
            this.detail.loading = true
            this.$http.post(this.moduleRout, this.detail.model).then((resp) => {
                this._endDetailLoading()
                cfg.callBack && cfg.callBack()
            }).catch(this._endDetailLoading())
        },
        _updateModel(cfg) {
            cfg = cfg || {}
            this.detail.loading = true
            this.$http.put(this.moduleRout, this.detail.model).then((resp) => {
                this._endDetailLoading()
                cfg.callBack && cfg.callBack()
            }).catch(this._endDetailLoading())
        },
        _batchUpdateField(cfg){
            cfg = cfg || {}
            this.$http.put(this.moduleRout+`/batch_update/${cfg.name}/${cfg.value}`, {ids: cfg.ids.join(',')}).then((resp) => {
                this.loadGrid()
                cfg.callBack && cfg.callBack()
            }).catch(cfg.errorCall())
        },
        _updateField(cfg) {
            cfg = cfg || {}
            this.$http.put(`${this.moduleRout}/update/${cfg.id}/${cfg.field}/${cfg.value}`).then((resp) => {
                cfg.callBack && cfg.callBack()
            }).catch(cfg.errorCall())
        },
        _suggest(cfg) {
            cfg = cfg || {}
            this.$http.get(this.suggest.moduleRout+"/suggest", {params: cfg.query || this.suggest.query}).then((resp) => {
                this.suggest.options = resp.data
                cfg.callBack && cfg.callBack()
            }).catch(console.warn.bind(console))
        },
        _renderExportData(data) {
            let renders = this.exportExcel.renders
            let ext = this.exportExcel.ext
            if(renders) {
                data.forEach(row => {
                    renders.keys.length > 0 && renders.keys.forEach(key => row[key] = this.getColumnRender(key)(row))
                    for (let k in renders.selfs) {
                        row[k] = renders.selfs[k](row, ext)
                    }
                })
            }
            return data
        },
        _endDetailLoading(){
            this.detail.loading = false
        }
    },
    filters: {
        rowsStatesDisabledFilters(data){
            let rows = [], states = null
            if(data instanceof Array){
                rows = data
            }else{
                rows = data.rows
                states = data.states
            }
            if(rows.length > 0) {
                rows.forEach(function (row, index, arr) {
                    row._disabled = utils.isDisabeldStates(row.states, states)
                })
            }
            return rows
        }
    }
}
